﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ParserGenerator.GrammarConstruction;

namespace ParserGenerator.ParserConstruction
{
    [Serializable]
    public sealed class ParserAutomatonReductions : ReadOnlyDictionary<GrammarProduction, ParserAutomatonReduction>
    {
        public ParserAutomatonState State { get; }

        internal ParserAutomatonReductions(ParserAutomatonState state)
            : base(new Dictionary<GrammarProduction, ParserAutomatonReduction>())
        {
            if (state == null)
                throw new ArgumentNullException(nameof(state));
            State = state;
        }

        internal ParserAutomatonReductions(ParserAutomatonState state, ParserAutomatonReductions other)
            : this(state)
        {
            if (other == null)
                throw new ArgumentNullException(nameof(other));
            foreach (ParserAutomatonReduction reduce in other.Dictionary.Values)
                Add(reduce.Production);
        }

        internal void Add(GrammarProduction production)
        {
            if (production == null)
                throw new ArgumentNullException(nameof(production));
            ParserAutomatonReduction reduce = new ParserAutomatonReduction(State, production);
            Dictionary.Add(production, reduce);
        }

        public ParserAutomatonReduction GetReduction(GrammarProduction production)
        {
            if (production == null)
                throw new ArgumentNullException(nameof(production));
            ParserAutomatonReduction reduce;
            if (!Dictionary.TryGetValue(production, out reduce))
            {
                string message = string.Format(SR.NoReductionDefinedForStateAndProduction, State, production);
                InvalidOperationException e = new InvalidOperationException(message);
                throw e;
            }
            return reduce;
        }
    }
}
